﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright company="DHGMS Solutions" file="Base.cs">
//   2004-2012 DHGMS Solutions. Some Rights Reserved. Licensed under GNU General Public License version 2 (GPLv2)
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Dhgms.TplHelper.Controller.Task
{
    using System;
    using System.Threading.Tasks;

    using Dhgms.TplHelper.Model.Info;
    using Dhgms.TplHelper.Model.Info.TaskResult;


    /// <summary>
    /// Base class for a task
    /// </summary>
    /// <typeparam name="TTaskResultClass">
    /// The type of result being returned by the task
    /// </typeparam>
    public abstract class Base<TTaskResultClass>
        where TTaskResultClass : TaskResultBase, new()
    {
        /// <summary>
        /// Name of the current task
        /// </summary>
        private readonly string name;

        /// <summary>
        /// THe single instance of the task
        /// </summary>
        private readonly Lazy<System.Threading.Tasks.Task<TTaskResultClass>> taskInstance;

        /// <summary>
        /// Initializes a new instance of the <see cref="Base{TTaskResultClass}"/> class. 
        /// </summary>
        /// <param name="name">
        /// The task Name.
        /// </param>
        protected Base(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException("name");
            }

            this.name = name;
            this.taskInstance = new Lazy<System.Threading.Tasks.Task<TTaskResultClass>>(() => new Task<TTaskResultClass>(this.Execute));
        }

        /// <summary>
        /// Gets the TPL Task
        /// </summary>
        public System.Threading.Tasks.Task<TTaskResultClass> Task
        {
            get
            {
                return this.taskInstance.Value;
            }
        }

        /// <summary>Entry point for doing the donkey work.</summary>
        /// <returns>The Execution Result.</returns>
        internal TTaskResultClass Execute()
        {
            var started = DateTime.Now;
            Console.WriteLine("Starting Task: " + this.name);
            var result = new TTaskResultClass();
            this.OnProcess(result);
            Console.WriteLine("Finished Task: " + this.name);

            result.Name = this.name;
            result.Started = started;
            result.Finished = DateTime.Now;
            return result;
        }

        /// <summary>
        /// The OnProcess event for doing the donkey work
        /// </summary>
        protected abstract void OnProcess(TTaskResultClass resultInformation);
    }
}